import { defineStore } from 'pinia'
import cos from '@/hook/useCos.js';
import { ElMessageBox } from 'element-plus'
import dayjs from 'dayjs'
// import mapTool from '@/hook/useBaiduMap'

// note(noteId,noteUserid,noteUsername,noteSendtime,noteType,noteInfo,
// noteContent,noteTime,noteImgs,noteVideos,noteAudios,noteFiles,noteLocation,notePeople,noteTags)
// noteImgs,noteVideos,noteAudios,noteFiles 是文件，需要上传，其中img需要传两个文件

let keysPath = [['noteImgs', 'compress-imgs/'], ['noteImgs', 'note-imgs/'], ['noteAudios', 'note-audios/'], ['noteVideos', 'note-videos/'], ['noteFiles', 'note-files/']]

export const useNote = defineStore('note', {
  state: () => ({
    notes: [],
    tags: [],
    todos: [],
    status: false
  }),
  actions: {
    init() {
      this.getNotes(notes => {
        this.notes = notes
        this.status = true
        myMsgS('获取到 ' + notes.length + ' 条记录')
      })
      this.getTags(data => this.tags = data)
      this.getTodos(data => this.todos = data)
      return this
    },
    // 获取全部Notes和Tags================================
    getNotes(fun) {
      console.log("访问note")
      myPost("/note/notes", { userToken: User.token },
        notes => fun(this.handleNotes(notes))
      )
    },
    // 把数据解析一遍
    handleNotes(rawNotes) {
      for (const note of rawNotes) { // JSON转换，全部数据项都要有，为空就空集
        let keys = ['noteImgs', 'noteVideos', 'noteAudios', 'noteFiles', 'noteLocation', 'notePeople', 'noteTags', 'noteInfo']
        for (const key of keys) note[key] = note[key] ? JSON.parse(note[key]) : []
      }
      return rawNotes
    },
    // 返回用户的全部tags
    getTags(fun) {
      myPost("/note/tags_all", { userToken: User.token },
        tags => fun(tags || [])
      )
    },
    // 返回用户的全部todos
    getTodos(fun) {
      myPost("/note/todos_all", { userToken: User.token },
        todos => fun(todos || [])
      )
    },

    addNote(value) {  // 添加note，并按照时间排序
      this.notes.push(value)
      this.notes.sort((a, b) => { return dayjs(b.noteTime).valueOf() - dayjs(a.noteTime).valueOf() })
    },
    addTodo(value) {
      this.todos.push(value)
      this.todos.sort((a, b) => { return dayjs(b.noteTime).valueOf() - dayjs(a.noteTime).valueOf() })
    },
    // 删除本地note，传入id或者note对象
    delNote(value) {
      if (typeof value != 'number') this.notes.splice(this.notes.indexOf(value), 1)
      else this.notes.splice(this.notes.findIndex(note => note.id === value), 1)
    },
    // 上传note相关=======================
    // 先传文件，再发请求
    releaseNote(editNote, func, uploadInfo) {
      cos.myUls(this.getFiles(editNote), () => {
        console.log("上传完毕，接着向数据库发请求")
        this.releaseNoteRaw(editNote, func)
      }, uploadInfo)
    },
    // 发送note，不上传数据
    releaseNoteRaw(editNote, func) {
      let noteRaw = {
        noteType: "", noteTime: dayjs().format(), notePeople: [], noteTags: [],
        noteImgs: [], noteVideos: [], noteAudios: [], noteFiles: [],
        ...editNote,
      }
      // 删除多余的数据项
      for (const key in noteRaw) if (key.indexOf('note')) delete noteRaw[key]

      myPost("/note/release", { userToken: User.token, noteJson: JSON.stringify(noteRaw) },
        note => {
          myMsgS("成功发布 1 条记录")
          this.addNote(this.handleNotes([note])[0])
          func && func(note)
        })
    },
    releaseTodo(editNote, func) {
      this.releaseNoteRaw(editNote, note => {
        console.log('🐔[note.js-actions:99] ', note)
        this.addTodo(note)
        func && func(note)
      })
    },
    // 提取文件，releaseNote和note修改要用到
    getFiles(editNote) {
      let files = []
      if (editNote.fImgs?.length) {
        for (const value of editNote.fImgs) { // 导入原图&压缩图
          files.push({ Key: "compress-imgs/" + value.key, Body: value.compressImg }) // 压缩
          if (editNote.isRawImgs) files.push({ Key: "note-imgs/" + value.key, Body: value.raw }) // 原图
          else files.push({ Key: "note-imgs/" + value.key, Body: value.compressImg95 }) // 95压缩
        }
      }
      if (editNote.fVideos?.length) {
        for (const value of editNote.fVideos) {
          files.push({ Key: "note-videos/" + value.key, Body: value.raw })
        }
      }
      if (editNote.fFiles?.length) {
        for (const value of editNote.fFiles) {
          files.push({ Key: "note-files/" + value.key, Body: value.raw })
        }
      }
      return files;
    },
    deleteNote(note, callback) {
      // 提取文件keys
      let keys = []
      for (const v of keysPath) keys.push(...note[v[0]].map(i => v[1] + i))

      ElMessageBox.confirm('确定要删除吗?', '删除记录', { type: 'warning' })
        .then(() => { // 点击确定，先删文件，再删记录
          cos.myRms(keys, () => {
            myPost("/note/delete", { noteId: note.noteId, userToken: User.token }, data => {
              myMsgS("成功删除" + data + "条记录")
              this.delNote(note)
              callback && callback(data)
            })
          })
        }).catch(() => { }) // 点击取消
    },
    // 修改、更新 note, 先上传文件，再调updateNoteRaw
    // 参三可选，直接传note的地址，这个方法就不用去找了
    updateNote(editNote, callback, uploadInfo) {
      cos.myUls(this.getFiles(editNote), () => this.updateNoteRaw(editNote, callback), uploadInfo)
    },
    // 修改、更新 note, 只负责发服务器请求，不负责上传文件
    // 参三可选，直接传note的地址，这个方法就不用去找了
    // 更新数据并删除需要覆盖数据文件
    updateNoteRaw(editNote, callback) {
      // 记录要删除的文件
      console.log(editNote)
      let delFiles = []
      if (editNote.isCoverImgs) delFiles.push(...editNote.rawImgs.map(i => 'compress-imgs/' + i), ...editNote.rawImgs.map(i => 'note-imgs/' + i))
      if (editNote.isCoverVideos) delFiles.push(...editNote.rawVideos.map(i => 'note-videos/' + i))
      if (editNote.isCoverAudios) delFiles.push(...editNote.rawAudios.map(i => 'note-audios/' + i))
      if (editNote.isCoverFiles) delFiles.push(...editNote.rawFiles.map(i => 'note-files/' + i))
      if (editNote.noteInfo) editNote.noteInfo = JSON.stringify(editNote.noteInfo)
      // 去除多余的数据项
      let noteRaw = { ...editNote }
      for (const key in noteRaw) if (key.indexOf('note')) delete noteRaw[key]
      console.log(noteRaw)

      myPost("/note/update", { userToken: User.token, noteJson: JSON.stringify(noteRaw) }, (data) => {
        cos.myRms(delFiles, () => {
          // 更新本地数据
          let note = this.notes.find(note => note.noteId == noteRaw.noteId)
          for (const key in noteRaw) note[key] = noteRaw[key]
          this.notes.sort((a, b) => { return dayjs(b.noteTime).valueOf() - dayjs(a.noteTime).valueOf() })
          myMsgS("成功更新" + data + "条记录")
          callback && callback(data)
        })
      })
    },

    // 批量设置type
    setType(ids, value, callback) {
      ids = ids.toString()
      myPost("/note/set_types", { ids, value, userToken: User.token },
        data => callback && callback(data))
    },

    // 生产view方法================================
    getView(notes) {
      let noteView = { xx: {}, mt: {}, mz: {}, my: {}, mn: {} }, timestamp

      notes.forEach(note => {
        // 详细 xx
        timestamp = dayjs(note.noteTime).format('YYYY-MM-DD HH:mm')// + ' 周' + dayjs(note.noteTime).day()
        if (noteView.xx[timestamp]) noteView.xx[timestamp].push(note)
        else noteView.xx[timestamp] = [note]

        // 每周 mz
        timestamp = dayjs(note.noteTime).day(0).format("YYYY-MM-DD"); // 当前周的第一天
        if (noteView.mz[timestamp]) noteView.mz[timestamp].push(note)
        else noteView.mz[timestamp] = [note]

        // 每天 每月 每年 mt my mn
        timestamp = dayjs(note.noteTime).format("YYYY-MM-DD")
        if (noteView.mt[timestamp]) noteView.mt[timestamp].push(note)
        else noteView.mt[timestamp] = [note]

        timestamp = dayjs(note.noteTime).format("YYYY年MM月")
        if (noteView.my[timestamp]) noteView.my[timestamp].push(note)
        else noteView.my[timestamp] = [note]

        timestamp = dayjs(note.noteTime).format("YYYY年")
        if (noteView.mn[timestamp]) noteView.mn[timestamp].push(note)
        else noteView.mn[timestamp] = [note]

      })
      return noteView;
    },
    // 获取带有坐标的记录，地图用
    getNotesWithLocations() {
      return this.notes.filter(note =>
        note.noteLocation.length
      )
    },
    // 获取带有图片的记录，地图用


    getNotesWithImgs() {
      return this.notes.filter(note =>
        note.noteImgs.length
      )
    },
  },
})
